
#ifndef WORLD_H_
#define WORLD_H_

int BLOCKS_ARRAY [128][48][128];
int WORLD_WIDTH;
int WORLD_HEIGHT;
int WORLD_DEPTH;

float *SCROLL_X, *SCROLL_Y, *SCROLL_Z;
float *ROT_X, *ROT_Y, *ROT_Z;
int SHOW_X = 16, SHOW_Y = 16, SHOW_Z = 16;
float selectedD;
int selectedX, selectedY, selectedZ;

void setSelected(float d, int x, int y, int z) {
	selectedD = d;
	selectedX = x;
	selectedY = y;
	selectedZ = z;
}

void scrollWorld(float* x, float* y, float* z) {
	SCROLL_X = x;
	SCROLL_Y = y;
	SCROLL_Z = z;
}

void rotateView(float* x, float* y, float* z) {
	ROT_X = x;
	ROT_Y = y;
	ROT_Z = z;
}

int getBlockId(int x, int y, int z) {
	if(x >= 0 && x < WORLD_WIDTH) {
		if(y >= 0 && y < WORLD_HEIGHT) {
			if(z >= 0 && z < WORLD_DEPTH) {
				return BLOCKS_ARRAY[x][y][z];
			}
		}
	}
	return 0;
}

void setBlockId(int x, int y, int z, int id) {
	if(x >= 0 && x < WORLD_WIDTH) {
		if(y >= 0 && y < WORLD_HEIGHT) {
			if(z >= 0 && z < WORLD_DEPTH) {
				BLOCKS_ARRAY[x][y][z] = id;
			}
		}
	}
}

void renderWorld() {
	for(int i = 0; i < SHOW_X; i++) {
		for(int k = 0; k < SHOW_Z; k++) {
			int light = (int)MAX_LIGHT-1;
			for(int j = SHOW_Y-1; j > 0; j--) {

				int x = i + (*SCROLL_X);
				int y = j + (*SCROLL_Y);
				int z = k + (*SCROLL_Z);

				int id = getBlockId(x, y, z);
				if(id == 0) continue;
				else if(light > 0) light--;
				Block* block = (getBlockWith(id));
				if(block == 0) continue;
				bool sides [6];
				int i2 = 0;
				for(int i1 = 0; i1 < 6; i1++) {
					sides[i1] = false;
					switch(i1) {
					case 0:
						sides[i1] = (getBlockId(x, y, z-1) == 0);
						if(k-SHOW_Z/2 < 0) sides[i1] = false;
						break;
					case 1:
						sides[i1] = (getBlockId(x, y, z+1) == 0);
						if(k-SHOW_Z/2 > 0) sides[i1] = false;
						break;
					case 2:
						sides[i1] = (getBlockId(x, y-1, z) == 0);
						if(j-SHOW_Y/2 < 0) sides[i1] = false;
						break;
					case 3:
						sides[i1] = (getBlockId(x, y+1, z) == 0);
						if(j-SHOW_Y/2 > 0) sides[i1] = false;
						break;
					case 4:
						sides[i1] = (getBlockId(x-1, y, z) == 0);
						if(i-SHOW_X/2 < 0) sides[i1] = false;
						break;
					case 5:
						sides[i1] = (getBlockId(x+1, y, z) == 0);
						if(i-SHOW_X/2 > 0) sides[i1] = false;
						break;
					default:
						break;
					}
					if(!sides[i1]) i2++;
				}
				if(i2 == 6) continue;

				if(x == selectedX && y == selectedY && z == selectedZ) {
					drawCube((x-*SCROLL_X)-(SHOW_X/2), (y-*SCROLL_Y)-(SHOW_Y/2), (z-*SCROLL_Z)-(SHOW_Z/2), sides, &select, light);
				} else {
					drawCube((x-*SCROLL_X)-(SHOW_X/2), (y-*SCROLL_Y)-(SHOW_Y/2), (z-*SCROLL_Z)-(SHOW_Z/2), sides, block, light);
				}
			}
		}
	}
}

void createWorld(int w, int h, int d) {
	WORLD_WIDTH = w;
	WORLD_HEIGHT = h;
	WORLD_DEPTH = d;
	int high = rand()%(h);
	bool sand_biome = false;
	for(int i = 0; i < w; i++) {
		if(rand()%32 == 0) high += (rand()%3-1);
		if(high < 0) high = 0;
		if(high >= WORLD_HEIGHT) high = WORLD_HEIGHT-1;
		if(rand()%32*32 == 0) sand_biome = !sand_biome;
		for(int k = 0; k < d; k++) {
			if(rand()%64 == 0) high += (rand()%3-1);
			if(high < 0) high = 0;
			if(high >= WORLD_HEIGHT) high = WORLD_HEIGHT-1;
			for(int j = 0; j < h; j++) {
				if(j > high) {
					setBlockId(i, j, k, 0);
					continue;
				} else
				if(j == 0) {
					setBlockId(i, j, k, bedrock.blockID);
					continue;
				} else
				if(j == high) {
					if(sand_biome) {
						setBlockId(i, j, k, sand.blockID);
					} else {
						setBlockId(i, j, k, grass.blockID);
					}
					continue;
				} else
				if(j < high && j >= high-3) {
					if(sand_biome) {
						setBlockId(i, j, k, sand.blockID);
					} else {
						setBlockId(i, j, k, dirt.blockID);
					}
					continue;
				} else
				if(j < high-3 && j > 0) {
					setBlockId(i, j, k, stone.blockID);
					continue;
				}
			}
		}
	}
}

#endif /* WORLD_H_ */
